package com.api.model;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public abstract class AbstractApi implements Api {

	private Map<Class<?>, Object> services = new HashMap<Class<?>, Object>();

	@Override
	public <T> T getService(Class<T> serviceClass) {

		return lazyInitService(serviceClass);
	}

	public <T> T lazyInitService(Class<T> serviceClass) {

		T service = null;

		if (services.containsKey(serviceClass)) {

			@SuppressWarnings("unchecked")
			T apiService = (T) services.get(serviceClass);
			service = apiService;
		} else {
			service = getProxyService(serviceClass);
			services.put(serviceClass, service);
		}
		return service;
	}

	public ApiRequestBuilder getRequest(Class<?> aClass, String methodName) {
		Method[] methods = aClass.getDeclaredMethods();
		List<Method> list = new ArrayList<Method>();
		for (Method method : methods) {
			if (method.getName().equals(methodName)) {
				list.add(method);
			}
		}
		if (list.size() == 0) {
			throw new IllegalArgumentException(
					String.format("Method name '%s' not found in class '%s'", methodName, aClass.getSimpleName()));
		} else if (list.size() > 1) {
			throw new IllegalStateException(String.format("There is more than one method named '%s' in class '%s'", methodName,
					aClass.getSimpleName()));
		}

		return getRequest(list.get(0));
	}

	protected abstract <T> T getProxyService(Class<T> serviceClass);
}
